#include "geometryengine.h"
#include <QLinearGradient>
#include <QPainter>
#include <QList>
#include <QColor>
#include <QVector2D>
#include <QVector3D>
#include <QtMath>
#include <QImage>

GeometryEngine::GeometryEngine() : indexBuf(QOpenGLBuffer::IndexBuffer)
{
    initializeOpenGLFunctions();
}

GeometryEngine::~GeometryEngine()
{
    vBuffer.destroy();
    indexBuf.destroy();
}

void GeometryEngine::addVectorData(CustomData* data,bool isString,bool isDepnedOther,ColorMap colorMap,QList<float> *lstRange)
{
    VertexData vertexData;
    QVector<uint> faceData;

    vBuffer.create();
    indexBuf.create();

    if(isString)
    {
        isExistData = data->IsExistStringData();
        vertexData = data->GetStringVertexData(isDepnedOther,lstRange,colorMap);
        faceData = data->GetStringFaceStripData();
        vertexNum = data->GetStringVertexCount();
        faceCount = data->GetStringFaceCount();
    }
    else
    {
        isExistData = data->IsExistWellData();
        vertexData = data->GetWellVertexData(isDepnedOther,lstRange,colorMap);
        faceData = data->GetWellFaceStripData();
        vertexNum = data->GetWellVertexCount();
        faceCount = data->GetWellFaceCount();
    }

    vBuffer.bind();
    vBuffer.allocate(vertexNum * (3*sizeof(QVector3D)+sizeof(QVector2D)));
    vBuffer.write(0,vertexData.position.data(),vertexNum * sizeof(QVector3D));
    vBuffer.write(vertexNum * sizeof(QVector3D),vertexData.color.data(),vertexNum * sizeof(QVector3D));
    vBuffer.write(vertexNum*2*sizeof(QVector3D),vertexData.normal.data(),vertexNum * sizeof(QVector3D));
    vBuffer.write(vertexNum*3*sizeof(QVector3D),vertexData.texCoord.data(),vertexNum * sizeof(QVector2D));


    indexBuf.bind();
    indexBuf.allocate(faceData.data(), faceCount * sizeof(GLuint));
}

void GeometryEngine::setColorMapByZ(CustomData* data,bool isString,ColorMap colorMap)
{
    if(!isExistData)
        return;
    vBuffer.bind();

    QVector<QVector3D> colorData = data->GetColorMapsByZ(isString,colorMap);
    vBuffer.write(vertexNum * sizeof(QVector3D),colorData.data(),vertexNum * sizeof(QVector3D));
}

 void GeometryEngine::setColorMapByName(CustomData* data,QString name,ColorMap colorMap)
 {
     if(!isExistData)
         return;
     vBuffer.bind();

     QVector<QVector3D> colorData = data->GetColorMapByName(name,colorMap);
     vBuffer.write(vertexNum * sizeof(QVector3D),colorData.data(),vertexNum * sizeof(QVector3D));
 }

void GeometryEngine::drawCubeGeometry(QOpenGLShaderProgram *program)
{
    if(!isExistData)
    {
        return;
    }
    // Tell OpenGL which VBOs to use
    vBuffer.bind();
    indexBuf.bind();

    // Offset for position
    quintptr offset = 0;

    // Tell OpenGL programmable pipeline how to locate vertex position data
    int vertexLocation = program->attributeLocation("vPosition");
    program->enableAttributeArray(vertexLocation);
    program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3,sizeof(QVector3D));

    offset += vertexNum * sizeof(QVector3D);
    int colorLocation = program->attributeLocation("a_color");
    program->enableAttributeArray(colorLocation);
    program->setAttributeBuffer(colorLocation, GL_FLOAT, offset, 3,sizeof(QVector3D));

    offset += vertexNum * sizeof(QVector3D);
    int normalLocation = program->attributeLocation("vNormal");
    program->enableAttributeArray(normalLocation);
    program->setAttributeBuffer(normalLocation, GL_FLOAT, offset, 3,sizeof(QVector3D));

    // Offset for texture coordinate
    offset += vertexNum * sizeof(QVector3D);

    // Tell OpenGL programmable pipeline how to locate vertex texture coordinate data
    int texcoordLocation = program->attributeLocation("a_texcoord");
    program->enableAttributeArray(texcoordLocation);
    program->setAttributeBuffer(texcoordLocation, GL_FLOAT, offset, 2, sizeof(QVector2D));

    // Draw cube geometry using indices from VBO 1
    glDrawElements(GL_TRIANGLE_STRIP,faceCount, GL_UNSIGNED_INT,0);


    program->disableAttributeArray(vertexLocation);
    program->disableAttributeArray(colorLocation);
    program->disableAttributeArray(normalLocation);
    program->disableAttributeArray(texcoordLocation);

    vBuffer.release();
    indexBuf.release();
}

